//@ts-check
import {
    clearJSONSpecialCode
} from "./raxios.util";
import {
    fireEvent
} from "../brower/event";

import axios from 'axios';

function quest(type, url, params, config) {
    var cancel = null,
        resolve, reject,
        promise = new Promise((res, rej) => {
            resolve = res;
            reject = rej;
        });
    //开始的钩子 
    config.onStart && config.onStart();

    if (config.onParams) {
        params = config.onParams(params)
    };
    if (config.onUrl) {
        url = config.onUrl(url)
    };

    axios[type](url, params, {
        cancelToken: new axios.CancelToken(c => cancel = c)
    }).catch(res => {
        error(res, url);
    }).then(function (res) {
        var data =res.data;
        //完成的钩子        	
        config.onComplete && config.onComplete();

        //对结果的处理
        if (config.onResult) {
            var result = config.onResult(data);

            if (result === -1) { //不处理
                return;
            }
            if (typeof result === 'string') {
                //错误信息
                reject(result);
            } else {
                //处理后的结果
                if (result.then) {
                    result.then(result => {
                        if (result === -1) { //不处理
                            return;
                        }
                        if (typeof result === 'string') {
                            //错误信息
                            reject(result);
                        } else {
                            //处理后的结果
                            resolve(result);
                        }
                    })
                } else {
                    resolve(result);
                }
            }
        } else {
            resolve(data);
        }
    }, function (err) {
        //完成的钩子         
        config.onComplete && config.onComplete();
        // 非请求取消，提示错误信息
        if (err.message !== '001') {
            var pro = config.onError && config.onError(err.message);
            if (typeof pro === 'object'&&pro.then) {
                pro.then((errMsg) => {
                    reject(errMsg);
                })
            } else {
                reject(err.message);
            }
        }
    });
    //@ts-ignore
    promise.cancel = cancel;
    return promise;
}

function blob(type, url, params, config) {
    //开始的钩子 
    config.onStart && config.onStart();

    var cancel = null,
        resolve, reject,
        promise = new Promise((res, rej) => {
            resolve = res;
            reject = rej;
        });

    if (config.onParams) {
        params = config.onParams(params)
    };
    if (config.onUrl) {
        url = config.onUrl(url)
    };

    axios[type](url, params, {
        responseType: 'blob',
        cancelToken: new axios.CancelToken(c => cancel = c)
    }).catch(res => {
        error(res, url);
    }).then(function (res) {
        //完成的钩子    	
        config.onComplete && config.onComplete();

        var data = res.data;
        var reader = new FileReader();
        if (data.type.indexOf('json') !== -1) {
            reader.readAsText(data);
            reader.onload = function (e) {
                // @ts-ignore
                var jdata = JSON.parse(e.target.result);
                //成功的钩子    	
                //对结果的处理
                if (config.onResult) {
                    var result = config.onResult(jdata);

                    if (result === -1) { //不处理
                        return;
                    }
                    if (typeof result === 'string') {
                        //错误信息
                        reject(result);
                    } else {
                        //处理后的结果
                        if (result.then) {
                            result.then(result => {
                                if (result === -1) { //不处理
                                    return;
                                }
                                if (typeof result === 'string') {
                                    //错误信息
                                    reject(result);
                                } else {
                                    //处理后的结果
                                    resolve(result);
                                }
                            })
                        } else {
                            resolve(result);
                        }
                    }
                } else {
                    resolve(jdata);
                }
            }
        } else {
            var fileName = res.headers['content-disposition'].match(/filename\*=utf-8\'\'(.*)/);
            reader.readAsDataURL(data);
            reader.onload = function (e) {
                // 转换完成，创建一个a标签用于下载        
                var a = document.createElement('a');
                a.download = decodeURI(fileName[1]);
                // @ts-ignore
                var Url = e.target.result;
                a.href = Url;
                document.body.appendChild(a)
                fireEvent(a, 'click');
                document.body.removeChild(a)
            }
        }
    }, function (err) {
        //完成的钩子         
        config.onComplete && config.onComplete();
        // 非请求取消，提示错误信息
        if (err.message !== '001') {
            var pro = config.onError && config.onError(err.message);
            if (typeof pro === 'object'&&pro.then) {
                pro.then((errMsg) => {
                    reject(errMsg);
                })
            } else {
                reject(err.message);
            }
        }
    });
    // @ts-ignore
    promise.cancel = cancel;
    return promise;
}

function error(res, url) {
    //处理请求异常。   
    if (axios.isCancel(res)) {
        throw new Error('001');
    } else {
        // http请求本身出错时    	
        if (res == 'Error: Network Error') {
            var msg = '网络异常。';
            throw new Error(msg);
        } else {
            var msg = '请求发生错误。';
            throw new Error(msg);
        }
        // @ts-ignore
        console.error(`http请求出错: Api:${url}  ${res}`);
    }
}

//处理配置
var globalConfig = {};

function getConf(conf) {
    if (conf.global !== false) {
        //覆盖globalConfig
        return Object.assign({}, globalConfig, conf)
    } else {
        return conf
    }
}
var raxios = {
    post(url, param, conf = {}) {
        return quest('post', url, param, getConf(conf))
    },
    get(url, param, conf = {}) {
        //拼接地址
        var query = ''
        if (param) {
            for (var i in param) {
                if (param.hasOwnProperty(i)) {
                    query += '&' + i + '=' + param[i]
                }
            }
        }
        if (url.indexOf('?') === -1) {
            query = '?' + query
        } else {
            query = query.slice(1)
        }
        url += query;

        return quest('get', url, param, getConf(conf))
    },
    download(url, param, conf = {}) {
        return blob('post', url, param, getConf(conf))
    },
    //	
    // download(url, param, config) { //	this.blob //	
    // },
    globalConfig(conf) {
        // onStart: noop,
        // onComplete: noop,
        // onResult: noop,
        // onParams: function (para) {
        //     return para
        // }
        Object.assign(globalConfig, conf);
    }
}
export default raxios